#!/usr/bin/env bash

sudo="$(command -v sudo)"
SUDO="$sudo"

if [[ -n "$BBX_DEBUG" ]]; then
  set -x
fi

os_type() {
  case "$(uname -s)" in
    Darwin*) echo "macOS";;
    Linux*)  echo "Linux";;
    MING*)   echo "win";;
    *)       echo "unknown";;
  esac
}

# Check if hostname is local (OG)
is_local_hostname() {
  local hostname="$1"
  local resolved_ips ip
  local public_dns_servers=("8.8.8.8" "1.1.1.1" "208.67.222.222")
  local has_valid_result=0
  for dns in "${public_dns_servers[@]}"; do
    resolved_ips=$(command -v dig >/dev/null 2>&1 && dig +short "$hostname" A @"$dns")
    if [[ "$?" -eq 0 ]] && [[ -n "$resolved_ips" ]]; then
      has_valid_result=1
      while IFS= read -r ip; do
        ip="${ip%.}"
        # Public if NOT in known private ranges
        if [[ ! "$ip" =~ ^(127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|::1$|fe80:) ]]; then
          return 1 # Public
        fi
      done <<< "$resolved_ips"
    fi
  done
  # If all results were private or none resolved, treat as local
  if [[ "$has_valid_result" -eq 1 ]]; then
    return 0 # All IPs private => local
  fi
  # Fallback: check /etc/hosts (or similar)
  if command -v getent &>/dev/null; then
    ip=$(getent hosts "$hostname" | awk '{print $1}' | head -n1)
    if [[ "$ip" =~ ^(127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|::1$|fe80:) ]]; then
      return 0 # Local
    fi
  fi
  return 0 # Unresolvable => local
}

initialize_package_manager() {
  local package_manager
  local amzn_release_info

  if command -v brew &>/dev/null; then
    package_manager=$(command -v brew)
  elif [[ "$(uname)" == "Darwin" ]]; then
    echo "ERROR: Homebrew not present. Please install Homebrew, or install certbot or letsencrypt client equivalent for macOS manually. But you may be better off using self-signed mkcert certificates if you are testing locally. If so please install and run:" >&2
    echo "brew install mkcert nss && mkcert -install && mkcert --cert-file fullchain.pem --key-file privkey.pem "$1" localhost 127.0.0.1" >&2
    exit 1
  elif command -v apt >/dev/null; then
    package_manager=$(command -v apt)
  elif command -v pkg &>/dev/null; then
    package_manager="$(command -v pkg)"
  elif command -v dnf >/dev/null; then
    package_manager=$(command -v dnf)
    $sudo dnf config-manager --set-enabled crb
    $sudo dnf -y upgrade --refresh
  elif command -v yum >/dev/null && [[ -f /etc/system-release ]]; then
    amzn_release_info=$(cat /etc/system-release)
    if [[ $amzn_release_info == *"Amazon Linux"* ]]; then
      package_manager=$(command -v yum)
    fi
  else
    echo "No supported package manager found. Exiting."
    return 1
  fi

  echo "Using package manager: $package_manager"
  export APT=$package_manager
}

initialize_package_manager

if ! command -v certbot >/dev/null; then
  if [ -f /etc/os-release ]; then
    . /etc/os-release
    if [[ $ID == "centos[O" || $ID == "rhel" || $ID == "fedora" || $ID_LIKE == *"centos"* || $ID_LIKE == *"rhel"* || $ID_LIKE == *"fedora"* || "$ID" == "almalinux" ]]; then
      $sudo yum install -y python3 augeas-libs
      $sudo python3 -m venv /opt/certbot/
      $sudo /opt/certbot/bin/pip install --upgrade pip
      $sudo /opt/certbot/bin/pip install certbot certbot-nginx
      $sudo ln -sf /opt/certbot/bin/certbot /usr/bin/certbot
      if ([ "$ID" = "almalinux" ] || [ "$ID" = "centos" ] || [ "$ID" = "rhel" ]) && [[ "$VERSION_ID" == 8* ]]; then
        echo "Detected AlmaLinux version starting with 8. Installing certbot and python3-certbot-apache."
        $sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
        $sudo dnf upgrade
        $sudo subscription-manager repos --enable "rhel-*-optional-rpms" --enable "rhel-*-extras-rpms"
        $sudo yum update
        $sudo dnf install -y certbot python3-certbot-apache
      fi
    elif [[ $ID == *"bsd" ]]; then
      $sudo $APT install -y py311-certbot curl
    else
      $sudo $APT install -y certbot curl
    fi
  else
    if [[ "$(uname)" == "Darwin" ]]; then
      $APT install certbot curl
    else
      $sudo $APT install -y certbot curl
    fi
  fi
fi

install_crontab() {
  if ! command -v crontab &>/dev/null; then
    echo "Crontab not found. Installing..."
    if [ "$(os_type)" == "macOS" ]; then
      brew install cronie
    elif [[ "$APT" == *yum || "$APT" == *dnf ]]; then
      $sudo $APT install -y cronie
      $sudo systemctl enable crond
      $sudo systemctl start crond
    else
      $sudo $APT install -y cron
      $sudo systemctl enable cron
      $sudo systemctl start cron
    fi
    echo "Crontab installation complete."
  else
    echo "Crontab is already installed."
  fi
}

install_crontab

if [[ -z "$1" ]]; then
  echo "Supply a domain name as first argument" >&2
  exit 1
fi

if [[ -z "${BB_USER_EMAIL}" ]]; then
  echo "Supply BB_USER_EMAIL environment variable" >&2
  exit 1
fi

# Use is_local_hostname to decide between certbot and mkcert
if ! is_local_hostname "$1"; then
  if $sudo certbot certonly --standalone --keep -d "$1" --agree-tos -m "${BB_USER_EMAIL}" --no-eff-email; then
    $sudo systemctl start certbot-renew.timer
    ./deploy-scripts/auto_cert_renew "$1" "$USER"
  else
    echo "ERROR: Certbot failed for non-local hostname $1" >&2
    exit 1
  fi
else
  echo "Detected local hostname $1, using mkcert for certificates" >&2
  if ! command -v jq &>/dev/null; then
    if [ "$(os_type)" == "macOS" ]; then
      brew install jq
    else
      $sudo $APT install -y jq
    fi
  fi

  hostname="$1"
  amd64=""

  if ! command -v mkcert &>/dev/null; then
    if [ "$(os_type)" == "macOS" ]; then
      brew install nss mkcert
    elif [ "$(os_type)" == "win" ]; then
      choco install mkcert || scoop bucket add extras && scoop install mkcert
    else
      amd64=$(dpkg --print-architecture || uname -m)
      $SUDO $APT install -y libnss3-tools
      curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/$amd64"
      chmod +x mkcert-v*-linux-$amd64
      $SUDO cp mkcert-v*-linux-$amd64 /usr/local/bin/mkcert
      rm mkcert-v*
    fi
  fi
  mkcert -install
  if [[ ! -f "$HOME/sslcerts/privkey.pem" || ! -f "$HOME/sslcerts/fullchain.pem" ]]; then
    :
  else
    echo "IMPORTANT: sslcerts already exist in $HOME/sslcerts directory. We ARE overwriting them."
  fi
  mkdir -p "$HOME/sslcerts"
  pwd=$(pwd)
  cd "$HOME/sslcerts"
  mkcert --cert-file fullchain.pem --key-file privkey.pem $1 localhost 127.0.0.1
  cd "$pwd"
fi

mkdir -p "$HOME/sslcerts"
if [[ -f ./cp_certs ]]; then
  $sudo -u root ./cp_certs "$1" "$HOME/sslcerts/"
elif [[ -f ./deploy-scripts/cp_certs ]]; then
  $sudo -u root ./deploy-scripts/cp_certs "$1" "$HOME/sslcerts/"
else
  $sudo -u root bash -c "bash <(curl -s https://raw.githubusercontent.com/BrowserBox/BrowserBox/main/deploy-scripts/cp_certs) \"$1\" \"$HOME/sslcerts/\""
fi
GROUP="$(id -gn || echo "$USER")"
$sudo chown "${USER}:${GROUP}" "$HOME/sslcerts/"*
chmod 600 "$HOME/sslcerts/"*
